home *** CD-ROM | disk | FTP | other *** search
- VGA Programming in Mode 13h
- -----------------------------------------------------------------------------
-
- This article will describe how to program VGA graphics Mode 13h using
- assembly language. Mode 13h is the 320x200x256 graphics mode, and is fast
- and very convenient from a programmers perspective.
-
- The video buffer begins at address A000:0000 and ends at address A000:F9FF.
- This means the buffer is 64000 bytes long and that each pixel in mode 13h
- is represented by one byte.
-
- It is easy to set up mode 13h and the video buffer in assembly language:
-
- mov ax,0013h ; Int 10 - Video BIOS Services
- int 10h ; ah = 00 - Set Video Mode
- ; al = 13 - Mode 13h (320x200x256)
-
- mov ax,0A000h ; point segment register es to A000h
- mov es,ax ; we can now access the video buffer as
- ; offsets from register es
-
- At the end of your program, you will probably want to restore the text
- mode. Here's how:
-
- mov ax,0003h ; Int 10 - Video BIOS Services
- int 10h ; ah = 00 - Set Video Mode
- ; al = 03 - Mode 03h (80x25x16 text)
-
- Accessing a specific pixel int the buffewr is also very easy:
-
- ; bx = x coordinate
- ; ax = y coordinate
- imul ax, 320 ; multiply y coord by 320 to get row
- add bx,ax ; add this with the x coord to get offset
- mov cx,es:[bx] ; now pixel x,y can be accessed as es:[bx]
-
- Hmm... That was easy, but that multiplication is slow and we should get
- rid of it. Thats easy to do too, simply by using bit shifting instead of
- multiplication. Shifting a number to the left is the same as multiplying
- by 2. We want to multiply by 320, which is not a multiple of 2, but
- 320 = 256 + 64, and 256 and 64 are both even multiples of 2. So a faster
- way to access a pixel is:
-
- ; bx = x coordinate
- ; ax = y coordinate
- mov cx,bx ; copy bx to cx, to save it temporatily
- shl cx,8 ; shift left by 8, which is the same as
- ; multiplying by 2^8 = 256
- shl bx,6 ; now shift left by 6, which is the same as
- ; multiplying by 2^6 = 64
- add bx,cx ; now add those two together, whis is
- ; effectively multiplying by 320
- add bx,ax ; finally add the x coord to this value
- mov cx,es:[bx] ; now pixel x,y can be accessed as es:[bx]
-
- Well, the code is a little bit longer and looks more complicated, but I
- can guarantee its much faster.
-
- To plot colors, we use a color look-up table. This look-up table is a
- 768 (3x256) array. Each index of the table is really the offset index*3.
- The 3 bytes at each index hold the corresponding values (0-63) of the red,
- green, and blue components. This gives a total of 262144 total possible
- colors. However, since the table is only 256 elements big, only 256
- different colors are possible at a given time.
-
- Changing the color palette is accomplished through the use of the I/O
- ports of the VGA card:
-
- Port 03C7h is the Palette Register Read port.
- Port 03C8h is the Palette Register Write port
- Port 03C9h is the Palette Data port
-
- Here is how to change the color palette:
-
- ; ax = palette index
- ; bl = red component (0-63)
- ; cl = green component (0-63)
- ; dl = blue component (0-63)
-
- mov dx,03C8h ; 03c8h = Palette Register Write port
- out dx,ax ; choose index
-
- mov dx,03C9h ; 03c8h = Palette Data port
- out dx,al
- mov bl,al ; set red value
- out dx,al
- mov cl,al ; set green value
- out dx,al
- mov dl,al ; set blue value
-
- Thats all there is to it. Reading the color palette is similar:
-
- ; ax = palette index
- ; bl = red component (0-63)
- ; cl = green component (0-63)
- ; dl = blue component (0-63)
-
- mov dx,03C7h ; 03c7h = Palette Register Read port
- out dx,ax ; choose index
-
- mov dx,03C9h ; 03c8h = Palette Data port
- in al,dx
- mov bl,al ; get red value
- in al,dx
- mov cl,al ; get green value
- in al,dx
- mov dl,al ; get blue value
-
- Now all we need to know is how to plot a pixel of a certain color at a
- certain location. Its very easy, given what we already know:
-
- ; bx = x coordinate
- ; ax = y coordinate
- ; dx = color (0-255)
- mov cx,bx ; copy bx to cx, to save it temporatily
- shl cx,8 ; shift left by 8, which is the same as
- ; multiplying by 2^8 = 256
- shl bx,6 ; now shift left by 6, which is the same as
- ; multiplying by 2^6 = 64
- add bx,cx ; now add those two together, whis is
- ; effectively multiplying by 320
- add bx,ax ; finally add the x coord to this value
- mov es:[bx],dx ; copy color dx into memory location
- ; thats all there is to it
-
- Ok, we now know how to set up Mode 13h, set up the video buffer, plot a
- pixel, and edit the color palette.
-
- My next article will go on to show how to draw lines, utilize the vertical
- retrace for smoother rendering, and anything else i can figure out by
- that time...
-
- -----------------------------------------------------------------------------
-
- Copyright (C) 1998
- Bill T. (billasm@usa.net)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-